﻿using System;
using System.IO;
using HgCo.WindowsLive.SkyDrive;
using API.WindowsLive.SkyDrive.Events;

namespace API.WindowsLive.SkyDrive.BusinessLogic
{
    partial class SkyDriveLogic
    {
        public void checkFilesInWebDirectory()
        {
            checkFilesInWebDirectory(localSyncRootDirectory);
        }

        private void checkFilesInWebDirectory(DirectoryInfo directoryInfo)
        {
            if (!webDirectoryExists(directoryInfo))
            {
                flagAllLocalFilesAsNotExists(directoryInfo);
                return;
            }

            FileInfo[] files = directoryInfo.GetFiles();
            foreach (FileInfo fileInfo in files)
            {
                if (!checkIfUploadFile(fileInfo))
                    markLocalFileAsNotExists(fileInfo);

            }

            DirectoryInfo[] directories = directoryInfo.GetDirectories();
            foreach (DirectoryInfo directoryInfoIteration in directories)
                checkFilesInWebDirectory(directoryInfoIteration);

        }

        public void Upload()
        {
            skyDrive.UploadWebFileProgressChanged += new EventHandler<UploadWebFileProgressChangedEventArgs>(skyDrive_UploadWebFileProgressChanged);

            processUploadDirectory(localSyncRootDirectory);
        }


        private void processUploadDirectory(DirectoryInfo directoryInfo)
        {
            if (!webDirectoryExists(directoryInfo))
            {
                createWebDirectory(directoryInfo);
            }

            WebFolderInfo currentWebFolder = getWebDirectory(directoryInfo);
            FileInfo[] files = directoryInfo.GetFiles();
            foreach (FileInfo fileInfo in files)
            {
                if (!checkIfUploadFile(fileInfo))
                {
                    uploadToWeb(fileInfo, currentWebFolder);
                }
            }

            DirectoryInfo[] directories = directoryInfo.GetDirectories();
            foreach (DirectoryInfo directoryInfoIteration in directories)
                processUploadDirectory(directoryInfoIteration);

        }//End of processing method

        String fileName = "";
        String fullFileName = "";
        long totalSize = 0;
        long partialUpload = 0;
        long uploadedSoFar = 0;

        private void uploadToWeb(FileInfo file, WebFolderInfo folder)
        {
            try
            {

                FileChanged(this, new FileChangedEventArgs(file.FullName, file.Name, 0, file.Length, FileChangedEventArgs.EventTypeEnum.upload));
                
                fileName = file.Name;
                fullFileName = file.FullName;
                totalSize = file.Length;
                partialUpload = 0;
                uploadedSoFar = 0;

                if (largeFileSplitter.isLargeFile(file))
                {
                    String[] splitFiles = largeFileSplitter.Split(file);
                    foreach (String splitFileName in splitFiles)
                    {
                        skyDrive.UploadWebFile(splitFileName, folder);
                        uploadedSoFar += partialUpload;
                    }
                    SplitLargeFiles.deleteFolder(splitFiles);
                }
                else
                {
                    skyDrive.UploadWebFile(file.FullName, folder);
                }

                FileChanged(this, new FileChangedEventArgs(file.FullName, file.Name, 0, file.Length, FileChangedEventArgs.EventTypeEnum.uploadCompleted));
            }
            catch (Exception ex)
            {
                ExceptionRaised(this, new ExceptionEventArgs(ex, ExceptionEventArgs.ExceptionLocationEnum.upload));
            }
        }

        void skyDrive_UploadWebFileProgressChanged(object sender, UploadWebFileProgressChangedEventArgs e)
        {
            partialUpload = e.BytesSent;
            if (totalSize < e.TotalBytesToSent)
                totalSize = e.TotalBytesToSent;
            FileChanged(this, new FileChangedEventArgs("", fileName, uploadedSoFar + partialUpload, totalSize, FileChangedEventArgs.EventTypeEnum.uploadProgress));
            //Console.WriteLine("Upload file: " + e.BytesSent);
        }

        private void flagAllLocalFilesAsNotExists(DirectoryInfo directoryInfo)
        {
            foreach (FileInfo file in directoryInfo.GetFiles())
            {
                markLocalFileAsNotExists(file);
            }

            foreach (DirectoryInfo directoryInfoIteration in directoryInfo.GetDirectories())
            {
                flagAllLocalFilesAsNotExists(directoryInfoIteration);
            }
        }

        private void markLocalFileAsNotExists(FileInfo file)
        {
            filesToUpload.Add(file);
            FileChanged(this, new FileChangedEventArgs(file.FullName, file.Name, 0, file.Length, FileChangedEventArgs.EventTypeEnum.addForUpload));
        }

        private Boolean fileInUploadList(FileInfo file)
        {
            foreach (FileInfo fileInfo in filesToUpload)
            {
                if (fileInfo.FullName.Equals(file.FullName))
                {
                    return true;
                }
            }
            return false;
        }

        public void deleteWebFilesIfNotInLocal()
        {
            deleteWebFilesIfNotInLocal(webSyncRootDirectory);
        }

        private void deleteWebFilesIfNotInLocal(WebFolderInfo webFolder)
        {
            if (!localDirectoryExists(webFolder))
            {
                FileChanged(this, new FileChangedEventArgs(webFolder.PathUrl, webFolder.Name, 0, 0, FileChangedEventArgs.EventTypeEnum.deleteWebFolder));
                skyDrive.DeleteWebFolder(webFolder);
                return;
            }

            WebFileInfo[] webFiles = getWebFiles(webFolder);
            foreach (WebFileInfo webFileInfo in webFiles)
            {
                WebFileInfo webFile = skyDrive.GetWebFile(webFileInfo);
                if (!checkIfDownloadFile(webFile, false))
                {
                    FileChanged(this, new FileChangedEventArgs(webFile.PathUrl, webFile.Name, 0, 0, FileChangedEventArgs.EventTypeEnum.deleteWebFile));
                    skyDrive.DeleteWebFile(webFile);
                }
            }

            WebFolderInfo[] subFolders = getSubDirectories(webFolder);
            foreach (WebFolderInfo webFolderInfo in subFolders)
            {
                WebFolderInfo webFolderIteration = skyDrive.GetWebFolder(webFolderInfo);
                deleteWebFilesIfNotInLocal(webFolderIteration);
            }
        }

    }
}
